package bbs.controller;


import bbs.annotation.GlobalInterceptor;
import bbs.annotation.VerifyParam;
import bbs.controller.base.ABaseController;
import bbs.entity.constants.Constants;
import bbs.entity.dto.CreateImageCode;
import bbs.entity.dto.SessionWebUserDto;
import bbs.entity.dto.SysSetting4CommentDto;
import bbs.entity.dto.SysSettingDto;
import bbs.entity.enums.RegisterEnum;
import bbs.entity.enums.ResponseCodeEnum;
import bbs.entity.enums.VerifyRegexEnum;
import bbs.entity.vo.ResponseVO;
import bbs.exception.BusinessException;
import bbs.service.EmailCodeService;
import bbs.service.UserInfoService;
import bbs.utils.SysCacheUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;


@RestController("accountController")
public class AccountController extends ABaseController {

    @Resource
    private EmailCodeService emailCodeService;

    @Resource
    private UserInfoService userInfoService;


    /**
     * 生成图片验证码
     * @param response
     * @param session
     * @param type
     * @throws IOException
     */
    @RequestMapping({"/checkCode"})
    public void checkCode(HttpServletResponse response, HttpSession session, Integer type) throws IOException {
        CreateImageCode vCode = new CreateImageCode(130, 38, 5, 10);
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0L);
        response.setContentType("image/jpeg");
        String str = vCode.getCode();
        if (type == null || type.intValue() == 0) {
            session.setAttribute(Constants.CHECK_CODE_KEY, str);
        } else {
            session.setAttribute(Constants.CHECK_CODE_KEY_EMAIL, str);
        }
        vCode.write((OutputStream)response.getOutputStream());
    }

    /**
     * 生成邮箱验证码
     * @param session
     * @param email
     * @param checkCode
     * @param type
     * @return
     */
    @RequestMapping({"/sendEmailCode"})
    @GlobalInterceptor(checkParams = true)
    public ResponseVO sendEmailCode(HttpSession session, @VerifyParam(required = true) String email, @VerifyParam(required = true) String checkCode, @VerifyParam(required = true) Integer type) {
        try {
            if (!checkCode.equalsIgnoreCase((String)session.getAttribute(Constants.CHECK_CODE_KEY_EMAIL)))
                throw new BusinessException(Constants.IMAGE_CODE_ERROR);
            this.emailCodeService.sendEmailCode(email, type);
            return getSuccessResponseVO(null);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY_EMAIL);
        }
    }

    /**
     * 注册
     * @param session
     * @param email
     * @param nickName
     * @param password
     * @param checkCode
     * @param emailCode
     * @return
     */
    @RequestMapping({"/register"})
    @GlobalInterceptor(checkParams = true)
    public ResponseVO register(HttpSession session,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.EMAIL, max = 50) String email,
                               @VerifyParam(required = true, max = 20) String nickName,
                               @VerifyParam(required = true, regex = VerifyRegexEnum.PASSWORD, min = 8, max = 18) String password,
                               @VerifyParam(required = true) String checkCode,
                               @VerifyParam(required = true) String emailCode)
    {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY)))
                throw new BusinessException(ResponseCodeEnum.CODE_600);
            this.userInfoService.register(email, nickName, password, emailCode);
            return getSuccessResponseVO(RegisterEnum.COMPLETED.getDesc());
        } catch (BusinessException e) {
            return getBusinessErrorResponseVO(e, new BusinessException(RegisterEnum.FAILED.getDesc()));
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }
    }


    /**
     * 用户登录
     * @param session
     * @param request
     * @param email
     * @param password
     * @param checkCode
     * @return
     */
    @RequestMapping({"/login"})
    @GlobalInterceptor(checkParams = true)
    public ResponseVO login(HttpSession session,
                               HttpServletRequest request,
                               @VerifyParam(required = true) String email,
                               @VerifyParam(required = true) String password,
                               @VerifyParam(required = true) String checkCode)
    {
        try {
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) throw new BusinessException(Constants.IMAGE_CODE_ERROR);
            SessionWebUserDto sessionWebUserDto = userInfoService.login(email, password, getIpAddress(request));
            session.setAttribute(Constants.SESSION_KEY, sessionWebUserDto);
            return getSuccessResponseVO(sessionWebUserDto);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }
    }

    /**
     * 获取用户信息
     * @param session
     * @return
     */
    @RequestMapping("/getUserInfo")
    @GlobalInterceptor()
    public ResponseVO getUserInfo(HttpSession session) {
        return getSuccessResponseVO(getUserInfoFromSession(session));
    }

    /**
     * 登出
     * @param session
     * @return
     */
    @RequestMapping("/logout")
    @GlobalInterceptor()
    public ResponseVO logout(HttpSession session) {
        session.invalidate();
        return getSuccessResponseVO(null);
    }

    /**
     * 获取系统设置
     * @return
     */
    @RequestMapping("/getSysSetting")
    @GlobalInterceptor()
    public ResponseVO getSysSetting() {
        SysSettingDto sysSettingDto = SysCacheUtils.getSysSetting();
        SysSetting4CommentDto commentDto = sysSettingDto.getCommentSetting();
        Map<String, Object> result = new HashMap<>();
        result.put("commentOpen", commentDto.getCommentOpen());
        return getSuccessResponseVO(result);
    }

    /**
     * 重置密码
     * @param session
     * @param email
     * @param password
     * @param emailCode
     * @param checkCode
     * @return
     */
    @RequestMapping("/resetPwd")
    @GlobalInterceptor()
    public ResponseVO resetPwd(
            HttpSession session,
            @VerifyParam(required = true) String email,
            @VerifyParam(required = true, min = 8, max = 18, regex = VerifyRegexEnum.PASSWORD) String password,
            @VerifyParam(required = true) String emailCode,
            @VerifyParam(required = true) String checkCode
    ) {
        try{
            if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) throw new BusinessException(Constants.IMAGE_CODE_ERROR);
            this.userInfoService.resetPwd(email, password, emailCode);
            return getSuccessResponseVO(null);
        } finally {
            session.removeAttribute(Constants.CHECK_CODE_KEY);
        }

    }
}
